package ar.edu.caece.compiler.grammar.factories;

import ar.edu.caece.compiler.grammar.AbstractTokenVisitorFactory;
import ar.edu.caece.compiler.grammar.GrammarSymbol;
import ar.edu.caece.compiler.grammar.TokenVisitorInterface;
import ar.edu.caece.compiler.grammar.nonterminals.ARRAY;
import ar.edu.caece.compiler.grammar.nonterminals.EXPR;
import ar.edu.caece.compiler.grammar.nonterminals.EXPR2;
import ar.edu.caece.compiler.grammar.nonterminals.EXPRA;
import ar.edu.caece.compiler.grammar.nonterminals.OTROSA;
import ar.edu.caece.compiler.grammar.nonterminals.PASOPAM2;
import ar.edu.caece.compiler.grammar.nonterminals.VALOR;
import ar.edu.caece.compiler.grammar.terminals.GrammarTerminal;

public class PASOPAM2Factory extends AbstractTokenVisitorFactory {

	private static PASOPAM2Factory INSTANCE;
	
	private OTROSAFactory otrosaFactory;
	private TokenVisitorInterface parseOTROSA;
	
	private ARRAYFactory arrayFactory;
	private TokenVisitorInterface parseARRAY;
	
	private VALORFactory valorFactory;
	private TokenVisitorInterface parseVALOR;
	
	public static PASOPAM2Factory getInstance() throws Exception {
		if(INSTANCE==null) INSTANCE = new PASOPAM2Factory();
		return INSTANCE;
	}
	
	private Initializer initializer = new Initializer() {
		
		@Override
		public void init() throws Exception {
			initializer = NoOperationInitializer.getInstance();
			otrosaFactory = OTROSAFactory.getInstance();
			parseOTROSA = otrosaFactory.makeVisitor();
			
			arrayFactory = ARRAYFactory.getInstance();
			parseARRAY = arrayFactory.makeVisitor();
			
			valorFactory = VALORFactory.getInstance();
			parseVALOR = valorFactory.makeVisitor();
		}
	};
	
	private PASOPAM2Factory() throws Exception {

	}
	
	@Override
	public TokenVisitorInterface makeChainedVisitor(
			final TokenVisitorInterface siguiente) throws Exception {
		initializer.init();

		return new TokenVisitorInterface() {

			@Override
			public GrammarSymbol defaultCase(GrammarTerminal llamador)
					throws Exception {
				GrammarSymbol result = llamador.execute(valorFactory.makeChainedVisitor(siguiente));
				if(result instanceof VALOR) {
					return new PASOPAM2 ((VALOR) result, 
							(ARRAY) nextToken().execute(parseARRAY), 
							(OTROSA) nextToken().execute(parseOTROSA)); 
				} 
				else {
					return result;
				}
			}
			
		};
	
	}
	@Override
	public TokenVisitorInterface makeVisitor() throws Exception {
		initializer.init();

		return new TokenVisitorInterface() {

			@Override
			public GrammarSymbol defaultCase(GrammarTerminal llamador)
					throws Exception {
				return new PASOPAM2 ((VALOR) llamador.execute(parseVALOR), (ARRAY) nextToken().execute(parseARRAY), (OTROSA) nextToken().execute(parseOTROSA));  
			}
		};
	}	
}
